package cn.sdormitory.exam.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.sdormitory.common.utils.SysUserUtils;
import cn.sdormitory.exam.dao.ExamInfoDao;
import cn.sdormitory.exam.dao.ExamResultInfoDao;
import cn.sdormitory.exam.service.ExamInfoService;
import cn.sdormitory.exam.vo.ExamConfigVo;
import cn.sdormitory.exam.vo.ExamInfoVO;
import cn.sdormitory.exam.vo.ExamResultInfoVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExamInfoServiceImpl extends ServiceImpl<ExamInfoDao, ExamInfoVO> implements ExamInfoService {

    @Resource
    private ExamInfoDao examInfoDao;

    @Resource
    private ExamResultInfoDao examResultInfoDao;

    @Override
    public IPage<ExamInfoVO> findExamInfoPageList(ExamInfoVO vo) {
        int count =  examInfoDao.findExamInfoPageListCount(vo);
        int startNum=(vo.getPageNum()-1)*vo.getPageSize();
        vo.setPageNum(startNum);
        List<ExamInfoVO> examInfoList =  examInfoDao.findExamInfoPageList(vo);

        // 匹配子集
        Set<Long> ids = examInfoList.stream().map(ExamInfoVO::getId).collect(Collectors.toSet());

        List<ExamInfoVO> children = null;
        if(ids.size() > 0){
            children = examInfoDao.getExamInfoChildrens(ids);
        }
/*        LambdaQueryWrapper<ExamInfoVO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ExamInfoVO::getPid, ids);
        List<ExamInfoVO> childrens = examInfoDao.selectList(queryWrapper);*/
        if (CollectionUtil.isNotEmpty(children)) {
            Map<Long, List<ExamInfoVO>> collect = children.stream().collect(Collectors.groupingBy(ExamInfoVO::getPid));
            for (ExamInfoVO infoVO : examInfoList) {
                List<ExamInfoVO> list = collect.get(infoVO.getId());
                infoVO.setChildren(list);
            }
        }

        IPage<ExamInfoVO> page = new Page<>();
        page.setTotal(count);
        page.setRecords(examInfoList);
        return page;
    }

    @Override
    public int addOrUpdateExamInfo(ExamInfoVO infoVO) {
        String userName = SysUserUtils.getSysUser().getUsername();
        // 修改
        if (!StringUtils.isEmpty(infoVO.getId())) {
            infoVO.setModifyBy(userName);
            infoVO.setModifyTime(new Date());
            return this.baseMapper.updateById(infoVO);
        }

        // 新增
        return this.baseMapper.insert(infoVO);
    }

    @Override
    public int deleteExamInfoById(ExamInfoVO examInfoVO) {
        int num = this.baseMapper.deleteById(examInfoVO.getId());
        if (Objects.nonNull(examInfoVO.getPid())) {
            examResultInfoDao.delete(new LambdaQueryWrapper<ExamResultInfoVO>().eq(ExamResultInfoVO::getResitExamId, examInfoVO.getId()));
        }
        examResultInfoDao.delete(new LambdaQueryWrapper<ExamResultInfoVO>().eq(ExamResultInfoVO::getExamId, examInfoVO.getId()));
        return num;
    }

    @Override
    @Transactional
    public int deleteBatchExamInfo(List<ExamInfoVO> list) {
        Set<Long> ids = list.stream().map(ExamInfoVO::getId).collect(Collectors.toSet());
        int num = this.baseMapper.deleteBatchIds(ids);
        // 还需删除考试结果的录入 根据考试信息id删除

        Set<Long> resitExamIds = new HashSet<>();
        for (ExamInfoVO infoVO : list) {
            if(Objects.nonNull(infoVO.getPid())) {
                resitExamIds.add(infoVO.getId());
            }
        }
        if (CollectionUtil.isNotEmpty(resitExamIds)) {
            LambdaQueryWrapper<ExamResultInfoVO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ExamResultInfoVO::getResitExamId, resitExamIds);
            examResultInfoDao.delete(queryWrapper);
        }
        LambdaQueryWrapper<ExamResultInfoVO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ExamResultInfoVO::getExamId, ids);
        examResultInfoDao.delete(queryWrapper);
        return num;
    }

    @Override
    public int updateBatchExamInfo(List<ExamInfoVO> list) {
        int num = 0;
        for (ExamInfoVO vo: list){
            this.baseMapper.updateById(vo);
            num ++ ;
        }
        return num;
    }


}
